#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include<string.h> 
#include "deamon_util.h"

#define LOCKFILE "/var/run/MTCU.pid"
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

void err_quit(const char *pFmt, const char *pCmd)
{
	printf(pFmt, pCmd);
	printf("\n");
	exit(0);
}

int already_running()
{
    int fd = open (LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
    if (fd < 0)
    {
        syslog(LOG_ERR, "can not open %s: %s \n", LOCKFILE, strerror(errno));
        return -1;
    }

    struct flock fl;
    fl.l_start = 0;
    fl.l_whence = SEEK_SET;
    fl.l_len = 0;
    fl.l_type = F_WRLCK;
    fl.l_pid = getpid();
 
    if (fcntl(fd, F_SETLK, &fl) < 0)
    {
    	if(errno == EACCES || errno == EAGAIN)//already locked
    	{
    		close(fd);
    		return -1;
    	}
    	syslog(LOG_ERR, "can not lock %s: %s \n", LOCKFILE, strerror(errno));
    	return -1;
    }

		char buf[1024]="";
		ftruncate(fd, 0);
 		sprintf(buf, "%ld", (long)getpid());
 		write(fd, buf, strlen(buf)+1);

    return 0;
}

void Daemon_init(const char *cmd, const char* dir)
{
    int                 i, fd0, fd1, fd2;
    pid_t               pid;
    struct rlimit       rl;
    struct sigaction    sa;

    //Clear file creation mask.
    umask(0);

    //Get maximum number of file descriptors.
    if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
        err_quit("%s: can not get file limit", cmd);


    //Become a session leader to lose controlling TTY.
    if ((pid = fork()) < 0)
        err_quit("%s: can not fork", cmd);
    else if (pid != 0) // parent
        exit(0);
    setsid();


    //Ensure future opens won't allocate controlling TTYs.
    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGHUP, &sa, NULL) < 0)
        err_quit("%s: can not ignore SIGHUP", cmd);
    if ((pid = fork()) < 0)
        err_quit("%s: can not fork", cmd);
    else if (pid != 0) // parent
        exit(0);

    //Change the current working directory
	if (chdir(dir) < 0)
        err_quit("%s: can not change directory to /", cmd);

   //Close all open file descriptors.
   if (rl.rlim_max == RLIM_INFINITY)
       rl.rlim_max = 1024;
	for (i = 0; i < rl.rlim_max; i++)
      close(i);

    
   //Attach file descriptors 0, 1, and 2 to /dev/null.   
   fd0 = open("/dev/null", O_RDWR);
   fd1 = dup(0);
   fd2 = dup(0);

   
    //Initialize the log file. 
    openlog(cmd, LOG_CONS, LOG_DAEMON);

    if (fd0 != 0 || fd1 != 1 || fd2 != 2)
    {
        syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2);
        exit(1);
    }
}
